#include"list.h"

//获取一个新的节点
list_node new_list_node(){
    return (list_node)calloc(1,sizeof(list_node_));
}

//创建链表
list_node create_list(){
    list_node head=new_list_node();
    head->next=NULL;
    head->data=NULL;
    return head;
}

//从头部插入
list_node add_node(list_node head,void* data){
    
    list_node temp=head;

    if(temp==NULL){
        return NULL;
    }else if(temp->data==NULL){
        temp->data=data;
    }else{
        list_node node=new_list_node();
        node->data=data;
        node->next=temp;
        temp=node;
    }

    return temp;
}

//查找节点
//如果没找到则返回-1,否则返回其在链表中的位置
int find_node(list_node head,void *data,int (*equal)(void* data,void *other)){
    list_node temp=head;
    int i=0;
    while(temp!=NULL && temp->data!=NULL){
        if(equal(data,temp->data)==0)
            return i;
        else{
            temp=temp->next;
            i++;
        }
    }
    return -1;
}

//判断链表是否为空
int is_list_empty(list_node this){
    return this->data==NULL;
}

//删除节点
//通过查找函数得到的结果删除
list_node delete_node(list_node head,int index){
        if(index<0 || head==NULL)return head;

        list_node target=NULL;
        if(index==0){
            //只有一个节点
            if(head->next==NULL){
                head->data=NULL;
                return head;
            }else{
                target=head;
                head=head->next;
            }
        }else{
            list_node temp=head;
            for(int i=1;i<index && temp->next!=NULL;i++)
                temp=temp->next;
            //index过大
            if(temp->next==NULL)
                return head;
            //找到了目标的前一个节点
            target=temp->next;
            temp->next=target->next;
        }
        free(target);
    
    return head;
}

//遍历链表
void iter_list(const list_node head,void (*func)(void* data)){
    list_node temp=head;
    while(temp!=NULL){
        func(temp->data);
        temp=temp->next;
    }
}

//清空链表
void clear_list(list_node head){
    while(head!=NULL){
        list_node temp=head;
        head=head->next;
        if(temp->data!=NULL)free(temp->data);
        free(temp);
    }
}